package com.lechi.web.controller;


import cn.hutool.json.JSONUtil;
import com.lechi.iot.netty.utils.NettyCacheUtils;
import com.lechi.web.common.core.controller.BaseController;
import com.lechi.web.common.core.domain.AjaxResult;
import com.lechi.web.common.core.page.TableDataInfo;
import com.lechi.web.common.enums.ErrorCodeEnum;
import com.lechi.web.common.exception.ServiceException;
import com.lechi.web.common.utils.poi.ExcelUtil;
import com.lechi.web.runner.CacheAlarmRules;
import com.lechi.web.service.IIotAlertRecordService;
import com.lechi.web.service.IIotTriggerRulesService;
import com.lechi.web.system.domain.IotAlertRecord;
import com.lechi.web.system.domain.IotTriggerRules;
import com.lechi.web.vo.IotTriggerRulesVo;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

/**
 * 数据分析规则Controller
 *
 * @author yangguang
 * @date 2024 -05-10
 */
@Slf4j
@RestController
@RequestMapping("/iot/rules")
@RequiredArgsConstructor
public class IotTriggerRulesController extends BaseController {


    private final IIotTriggerRulesService iotTriggerRulesService;


    private final IIotAlertRecordService iotAlertRecordService;

    private final CacheAlarmRules cacheAlarmRules;


    /**
     * 查询数据分析规则列表
     *
     * @param iotTriggerRules the iot trigger rules
     * @return the table data info
     */
    @GetMapping("/list")
    //    @PreAuthorize("@ss.hasPermi('iot:file:remove')")
    public TableDataInfo list(IotTriggerRules iotTriggerRules) {
        startPage();
        List<IotTriggerRules> list = iotTriggerRulesService.selectIotTriggerRulesList(iotTriggerRules);
        return getDataTable(list);
    }

    /**
     * 导出数据分析规则列表
     *
     * @param response        the response
     * @param iotTriggerRules the iot trigger rules
     */
    @PostMapping("/export")
    public void export(HttpServletResponse response, IotTriggerRules iotTriggerRules) {
        List<IotTriggerRules> list = iotTriggerRulesService.selectIotTriggerRulesList(iotTriggerRules);
        ExcelUtil<IotTriggerRules> util = new ExcelUtil<IotTriggerRules>(IotTriggerRules.class);
        util.exportExcel(response, list, "数据分析规则数据");
    }

    /**
     * 获取数据分析规则详细信息
     *
     * @param id the id
     * @return the info
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(iotTriggerRulesService.selectIotTriggerRulesById(id));
    }

    /**
     * 新增数据分析规则
     *
     * @param iotTriggerRulesVo the iot trigger rules vo
     * @return the ajax result
     */
    @PostMapping("/add")
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public AjaxResult add(@RequestBody IotTriggerRulesVo iotTriggerRulesVo) {
        IotTriggerRules iotTriggerRules = new IotTriggerRules();
        BeanUtils.copyProperties(iotTriggerRulesVo, iotTriggerRules);
        iotTriggerRules.setRuleContext(JSONUtil.toJsonStr(JSONUtil.parseArray(iotTriggerRulesVo.getRuleContext())));
        if (iotTriggerRulesVo.getId() == -1) {
            iotTriggerRulesService.insertIotTriggerRules(iotTriggerRules);
        } else {
            iotTriggerRulesService.updateIotTriggerRules(iotTriggerRules);
        }
        NettyCacheUtils.remove("AlarmRuleType_" + iotTriggerRules.getDeviceId() + "_" + iotTriggerRules.getSensorAliasId());
        cacheAlarmRule(iotTriggerRulesVo.getDeviceId());
        return success();
    }

    /**
     * Cache alarm rule.
     *
     * @param deviceId the device id
     */
    public void cacheAlarmRule(Long deviceId) {
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                try {
                    String tempDeviceId = deviceId != null ? String.valueOf(deviceId) : null;
                    cacheAlarmRules.run(tempDeviceId);
                } catch (Exception e) {
                    throw new ServiceException(ErrorCodeEnum.CMD_PARSE_CACHE_ERROR.getValue(), ErrorCodeEnum.CMD_PARSE_CACHE_ERROR.getKey());
                }
            }
        });
    }

    /**
     * 删除数据分析规则
     *
     * @param ids the ids
     * @return the ajax result
     */
    @DeleteMapping("/{ids}")
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public AjaxResult remove(@PathVariable Long[] ids) {
        Arrays.stream(ids).forEach(triggerId -> {
            final IotTriggerRules iotTriggerRules = iotTriggerRulesService.selectIotTriggerRulesById(triggerId);
            if (iotTriggerRules == null) {
                return;
            }
            IotAlertRecord iotAlertRecord = new IotAlertRecord();
            BeanUtils.copyProperties(iotTriggerRules, iotAlertRecord);
            iotAlertRecordService.deleteIotAlertRecord(iotAlertRecord);
            String alarmRuleKey = "AlarmRule_deviceId_sensorAliasId_" + iotTriggerRules.getDeviceId() + "_" + iotTriggerRules.getSensorAliasId();
            NettyCacheUtils.remove(alarmRuleKey);

            NettyCacheUtils.remove("AlarmRuleType_" + iotTriggerRules.getDeviceId() + "_" + iotTriggerRules.getSensorAliasId());
        });
        iotTriggerRulesService.deleteIotTriggerRulesByIds(ids);
        return success();
    }
}
